# coding:utf-8
import numpy as np
import  pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import normalize,StandardScaler
import time
# 封装成类方便进行操作
class Naivebayes:
    def __init__(self):
        self.length=-1
        self.traindic=dict()
        self.label_prob=dict()
        self.labelset=list()
    def trainbayes(self,traindata,label):
        self.length=len(traindata)
        # 首先用字典存起来边与计算概率
        for thistrain,thislabel in zip(traindata,label):
            # 要先将字典初始化一下
            if thislabel not in self.traindic:
                self.traindic[thislabel]=[]
            self.traindic[thislabel].append(thistrain.tolist())
#       接着得出label概率字典
        datalen=len(label)
        for thislabel,thisdatalist in self.traindic.items():
            self.label_prob[thislabel]=len(thisdatalist)/datalen
            self.labelset.append(thislabel)
        self.labelset=set(self.labelset)
        print('训练结束了！')
    def testbayes(self,testdata):
#          计算条件概率
        result={}
        for label in self.labelset:
            p=1
            p_c=self.label_prob[label]
            alltraindata=self.traindic[label]
            train_num=len(alltraindata)
            alltraindata=np.array(alltraindata).T
            for index in range(0,len(testdata)):
                vector=alltraindata[index].tolist()
                p*=vector.count(testdata[index])/train_num
            result[label]=p*p_c
        result_label=sorted(result,key=lambda x:result[x],reverse=True)[0]
        print("预测的结果是：")
        print(result)
        return result_label
if __name__ == '__main__':
    # 读取数据
    data = pd.read_csv('iris.csv', names=[1, 2, 3, 4, 'label'])
    # 将数据按照训练数据和测试数据进行切分
    X = data[[1, 2, 3, 4]].values
    y = data['label'].values
    # 将数据按照训练数据和测试数据进行切分
    X = data[[1, 2, 3, 4]].values
    # 进行正则化
    # X = normalize(X)
    # 进行标准化
    X = StandardScaler().fit_transform(X)
    acclist=[]
    time1=time.time()
    for i in range(10):
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
        right_count = 0
        clf = Naivebayes()
        clf.trainbayes(X_train, y_train)
        for thistest, thislabel in zip(X_test, y_test):
            result = clf.testbayes(thistest)
            if result == thislabel:
                right_count += 1
            # print(thistest)
            print("预测的结果是：" + result)
        acc = right_count / len(X_test)
        print("预测的准确率为：{}".format(acc))
        acclist.append(acc)
    print(acclist)
    avg_acc = np.array(acclist).mean()
    print("运行10次的平均准确率为：{}".format(avg_acc))
    time2=time.time()
    print("运行10次的时间为：{}".format(time2-time1))



